package xin.xihc.jba.sql;

import xin.xihc.jba.sql.clause.Clause;

import java.util.LinkedList;
import java.util.List;

import static xin.xihc.jba.sql.SqlConstants.*;

/**
 * Where子句
 *
 * @author Leo.Xi
 * @date 2020/1/14
 * @since 1.0
 **/
public class Where implements SqlType {

    private final List<String> wheres = new LinkedList<>();
    private KV kv = new KV();

    public Where() {
    }

    public Where(KV kv) {
        if (kv != null) {
            this.kv = kv;
        }
    }

    public Where(Where otherWhere) {
        this.kv.merge(otherWhere.kv);
        this.wheres.addAll(otherWhere.wheres);
    }

    /**
     * where的and条件
     *
     * @param clause 条件
     * @return
     */
    public Where and(Clause<?> clause) {
        if (null != clause) {
            wheres.add(AND);
            wheres.add(clause.toSql(this.kv));
        }
        return this;
    }

    /**
     * where的OR的条件列表
     *
     * @param clause 条件列表
     */
    public Where or(Clause<?> clause) {
        wheres.add(OR);
        wheres.add(clause.toSql(this.kv));
        return this;
    }

    /**
     * where的OR的条件列表
     *
     * @param clauses 条件列表
     */
    public Where or(Clause<?>... clauses) {
        if (clauses.length > 0) {
            wheres.add(OR);
            StringBuilder temp = new StringBuilder("(");
            temp.append(clauses[0].toSql(this.kv));
            for (int i = 1; i < clauses.length; i++) {
                temp.append(AND).append(clauses[i].toSql(this.kv));
            }
            temp.append(")");
            wheres.add(temp.toString());
        }
        return this;
    }

    /**
     * where的And(xxx='xxx' OR xx='www' OR xx='www')
     *
     * @param clauses 条件列表
     */
    public Where orInAnd(Clause<?>... clauses) {
        if (clauses.length > 0) {
            wheres.add(AND);
            StringBuilder temp = new StringBuilder("(");
            temp.append(clauses[0].toSql(this.kv));
            for (int i = 1; i < clauses.length; i++) {
                temp.append(OR).append(clauses[i].toSql(this.kv));
            }
            temp.append(")");
            wheres.add(temp.toString());
        }
        return this;
    }

    public KV getKv() {
        return this.kv;
    }

    /**
     * 去除where首尾的AND、OR
     *
     * @author Leo.Xi
     * @date 2020/1/18
     * @since 0.0.1
     */
    protected List<String> trimWhere() {
        if (this.wheres.size() < 1) {
            return this.wheres;
        }
        String first = this.wheres.get(0);
        String last = this.wheres.get(this.wheres.size() - 1);
        if (last.equals(AND) || last.equals(OR)) {
            this.wheres.remove(this.wheres.size() - 1);
        }
        if (first.equals(AND) || first.equals(OR)) {
            this.wheres.remove(0);
        }
        return this.wheres;
    }

    /**
     * 转为SQL语句
     *
     * @return sql
     * @author Leo.Xi
     * @date 2020/1/14
     * @since 0.0.1
     */
    @Override
    public String toSql() {
        if (this.wheres.size() > 0) {
            return action() + String.join("", trimWhere());
        }
        return BLANK;
    }

    /**
     * 操作类型
     *
     * @return SELECT、WHERE、UPDATE、ORDER BY、
     * @author Leo.Xi
     * @date 2020/1/18
     * @since 0.0.1
     */
    @Override
    public String action() {
        return WHERE;
    }
}